package com.xmall.auth.xmallauth.security;

import com.xmall.auth.xmallauth.jwt.filter.JWTAuthorizationFilter;
import com.xmall.auth.service.XmallUserDetailsService;
import com.xmall.auth.xmallauth.config.IgnoreUrlsConfig;
import com.xmall.auth.xmallauth.jwt.util.JwtTokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;


@Configuration
@EnableWebSecurity
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {

    @Autowired
    private XmallUserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
                //.passwordEncoder(bCryptPasswordEncoder());
       // auth.parentAuthenticationManager(authenticationManagerBean());
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http
                .authorizeRequests();
        //不需要保护的资源路径允许访问
        for (String url : ignoreUrlsConfig().getUrls()) {
            registry.antMatchers(url).permitAll();
        }
        //允许跨域请求的OPTIONS请求
        registry.antMatchers(HttpMethod.OPTIONS)
                .permitAll();

        registry.and()
                .csrf()
                .disable()
                .formLogin()
                .failureUrl("/login?error")
                .permitAll() //登录页面用户任意访问
                .and()
                .authorizeRequests()        // 定义哪些URL需要被保护、哪些不需要被保护
                .anyRequest()               // 任何请求,登录后可以访问
                .authenticated()
                .and()
                .exceptionHandling()
                .accessDeniedHandler(restfulAccessDeniedHandler())
                .and()
                .addFilterBefore(jWTAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class);
                //.addFilter(new JWTAuthenticationFilter(authenticationManager()));



        /*
        //允许跨域请求的OPTIONS请求
        registry.antMatchers(HttpMethod.OPTIONS)
                .permitAll();
        registry.and()
                .authorizeRequests()        // 定义哪些URL需要被保护、哪些不需要被保护
                .anyRequest()               // 任何请求,登录后可以访问
                .authenticated()
                .and()
                .csrf()
                .disable()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                *//*.formLogin()
                .failureUrl("/login?error")
                .permitAll() //登录页面用户任意访问*//*
                // 自定义权限拒绝处理类
                *//*.and()
                .exceptionHandling()
                .accessDeniedHandler(restfulAccessDeniedHandler())*//*
               // .authenticationEntryPoint(restAuthenticationEntryPoint())
                .and()
                .addFilter(new JWTAuthenticationFilter(authenticationManager()));*/


    }

    @Bean
    public IgnoreUrlsConfig ignoreUrlsConfig() {
        return new IgnoreUrlsConfig();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
  /*@Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable()
                .formLogin()
                .failureUrl("/login?error")
                .permitAll() //登录页面用户任意访问
                .and()
                .logout().permitAll()
                .and()//注销行为任意访问
                .authorizeRequests()
                // 测试用资源，需要验证了的用户才能访问
                .antMatchers("/user/**").authenticated()
                // 其他都放行了
                .anyRequest().permitAll()
                .and()
                // 不需要session
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
//http.addFilterBefore(new JWTAuthenticationFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class);
//http.addFilterBefore(new JWTAuthorizationFilter(authenticationManager()), BasicAuthenticationFilter.class);
*//*        http.addFilter(new JWTAuthenticationFilter(authenticationManager()))
                .addFilter(new JWTAuthorizationFilter(authenticationManager()));*//*
    }*/

    /*@Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()                    //  定义当需要用户登录时候，转到的登录页面。
                .and()
                .authorizeRequests()        // 定义哪些URL需要被保护、哪些不需要被保护
                .anyRequest()               // 任何请求,登录后可以访问
                .authenticated();
    }*/


   /* @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .inMemoryAuthentication()
                .passwordEncoder(new BCryptPasswordEncoder())
                .withUser("john.carnell").password( new BCryptPasswordEncoder().encode("password1")).roles("USER")
                .and()
                .passwordEncoder(new BCryptPasswordEncoder())
                .withUser("william.woodward").password(new BCryptPasswordEncoder().encode("password2")).roles("USER", "ADMIN");

    }*/

    @Bean
    public JwtTokenUtil jwtTokenUtil() {
        return new JwtTokenUtil();
    }
    @Bean
    public RestfulAccessDeniedHandler restfulAccessDeniedHandler() {
        return new RestfulAccessDeniedHandler();
    }
    @Bean
    public JWTAuthorizationFilter jWTAuthorizationFilter() {
        return new JWTAuthorizationFilter();
    }


}
